//id
module id_mod(
	rst,

	//输入使能
	id_en_i,

	//输入信号
	PC_i,
	mem_data_i,

	//判断转移J模块
	J_en_o,
	J_data_o,
	J_data1_o,
	J_addr_o,
	J_addrp_o,
	J_how_o,

	//控制alu模块
	alu_en_o,
	alu_reg_addr_o,
	alu_csr_addr_o,
	alu_data_o,
	alu_data1_o,
	alu_mcause_o,
	alu_mtval_o,
	alu_where_o,
	alu_how_o,
	

	//控制regs模块
	reg_addr_o,
	reg1_addr_o,
	reg_data_i,
	reg1_data_i,

	//控制csrs模块
	csr_addr_o,
	csr_data_i,
	csr_mtvec_i,
	csr_mepc_i,
	csr_mie_i,
	csr_mip_i,
	csr_mstatus_i,

	//暂停int模块
	c_int_o,


	//异常输入
	I_a_m_i,
	I_a_f_i,
	L_a_m_i,
	L_a_f_i,
	S_a_m_i,
	S_a_f_i,
	
	clint_data_i

);

input rst;

//输入使能
input id_en_i;

//输入信号
input [31:0] PC_i;
input [31:0] mem_data_i;

//判断转移J模块
output reg J_en_o;
output reg [31:0] J_data_o;
output reg [31:0] J_data1_o;
output reg [31:0] J_addr_o;
output reg [31:0] J_addrp_o;
output reg [2:0] J_how_o;

//控制alu模块
output reg alu_en_o;
output reg [4:0] alu_reg_addr_o;
output reg [11:0] alu_csr_addr_o;
output reg [1:0] alu_where_o;
output reg [7:0] alu_how_o; //剩余一半空间
output reg [31:0] alu_data_o;
output reg [31:0] alu_data1_o;
output reg [31:0] alu_mcause_o;
output reg [31:0] alu_mtval_o;



//控制regs模块
output [4:0] reg_addr_o;
output [4:0] reg1_addr_o;
input [31:0] reg_data_i;
input [31:0] reg1_data_i;

//控制csrs模块
output [11:0] csr_addr_o;
input [31:0] csr_data_i;
input [31:0] csr_mtvec_i;
input [31:0] csr_mepc_i;
input [31:0] csr_mie_i;
input [31:0] csr_mip_i;
input [31:0] csr_mstatus_i;

//暂停int模块
output reg c_int_o;


//异常输入
input I_a_m_i;
input I_a_f_i;
input L_a_m_i;
input L_a_f_i;
input S_a_m_i;
input S_a_f_i;

input [31:0] clint_data_i;

//生成“变量”
wire [24:0] imm317;
assign imm317 = mem_data_i[31:7];

wire [31:0] imm110s;
wire [31:0] imm3112;
wire [31:0] imm110i;
wire [31:0] imm201;
wire [31:0] imm121;
wire [31:0] zimm;

assign imm110s = {{20{imm317[24]}},imm317[24:18],imm317[4:0]};
assign imm3112 = {imm317[24:5],12'h0};
assign imm110i = {{20{imm317[24]}},imm317[24:13]};
assign imm201 = {{11{imm317[24]}},imm317[24],imm317[12:5],imm317[13],imm317[23:14],1'b0};
assign imm121 = {{19{imm317[24]}},imm317[24],imm317[0],imm317[23:18],imm317[4:1],1'b0};
assign zimm = {27'b0,mem_data_i[19:5]};
wire [4:0] rd;
wire [11:0] csr;

assign rd = mem_data_i[11:7];
assign csr = mem_data_i[31:20];

wire [5:0] shamt;
assign shamt = (mem_data_i[25]==1'b0)?mem_data_i[25:20]:6'b0;

assign reg_addr_o = mem_data_i[19:15];
assign reg1_addr_o = mem_data_i[24:20];
assign csr_addr_o = mem_data_i[31:20];

//开始执行
always @ ( * ) begin
	if (rst == 1'b1) begin
		J_en_o <= 1'b0;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= 32'b0;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b0;
		alu_data_o <= 32'b0;
		alu_data1_o <= 32'b0;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'b0;
		alu_mtval_o <= 32'b0;
		alu_where_o <= 2'b0;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b0;

	end else if (id_en_i == 1'b1) begin
	if (csr_mstatus_i[3] == 1'b1 && csr_mie_i[3] && csr_mip_i[3]) begin//中断处理:机器模式软件中断
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i[0] == 1'b1 ? csr_mtvec_i &(~32'b11) + (32'b1100) : csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h80000008;
		alu_mtval_o <= mem_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else if (csr_mstatus_i[3] == 1'b1 && csr_mie_i[7] && csr_mip_i[7]) begin//中断处理:机器模式时钟中断
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i[0] == 1'b1 ? csr_mtvec_i &(~32'b11) + (32'b11100) : csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h80000080;
		alu_mtval_o <= mem_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else if (csr_mstatus_i[3] == 1'b1 && csr_mie_i[11] && csr_mip_i[11]) begin//中断处理:机器模式其他中断
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i[0] == 1'b1 ? csr_mtvec_i &(~32'b11) + (32'b101100) : csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h80000800;
		alu_mtval_o <= clint_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else if (I_a_m_i == 1'b1) begin//异常处理:
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h0;
		alu_mtval_o <= mem_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else if (I_a_f_i == 1'b1) begin//异常处理
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h01;
		alu_mtval_o <= mem_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else if (L_a_m_i == 1'b1) begin//异常处理
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h04;
		alu_mtval_o <= mem_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else if (L_a_f_i == 1'b1) begin//异常处理
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h10;
		alu_mtval_o <= mem_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else if (S_a_m_i == 1'b1) begin//异常处理
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h20;
		alu_mtval_o <= mem_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else if (S_a_f_i == 1'b1) begin//异常处理
		J_en_o <= 1'b1;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= csr_mtvec_i;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b1;
		alu_data_o <= csr_mstatus_i;
		alu_data1_o <= PC_i;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'h40;
		alu_mtval_o <= mem_data_i;
		alu_where_o <= 2'h3;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b1;
	end else begin //译码
	casex(mem_data_i)
		32'b0000000??????????000?????0110011 : begin //add
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b0100000??????????000?????0110011 : begin //sub
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h1;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????111?????0110011 : begin //and
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h2;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????110?????0110011 : begin //or
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h3;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????100?????0110011 : begin //xor
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h4;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????001?????0110011 : begin //sll
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h5;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????101?????0110011 : begin //srl
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h6;
			c_int_o <= 1'b0;
		end

		32'b0100000??????????101?????0110011 : begin //sra
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h7;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????010?????0110011 : begin //slt
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h8;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????011?????0110011 : begin //sltu
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= reg1_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h9;
			c_int_o <= 1'b0;
		end

		32'b?????????????????000?????0010011 : begin //addi
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b?????????????????010?????0010011 : begin //slti
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h8;
			c_int_o <= 1'b0;
		end

		32'b?????????????????011?????0010011 : begin //sltiu
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h9;
			c_int_o <= 1'b0;
		end

		32'b?????????????????111?????0010011 : begin //andi
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h2;
			c_int_o <= 1'b0;
		end

		32'b?????????????????110?????0010011 : begin //ori
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h3;
			c_int_o <= 1'b0;
		end

		32'b?????????????????100?????0010011 : begin //xori
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h4;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????001?????0010011 : begin //slli
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= shamt;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h5;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????101?????0010011 : begin //srli
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= shamt;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h6;
			c_int_o <= 1'b0;
		end

		32'b0000000??????????101?????0010011 : begin //srai
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= shamt;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h7;
			c_int_o <= 1'b0;
		end

		32'b?????????????????????????0110111 : begin //lui
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= imm3112;
			alu_data1_o <= 31'b0;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b?????????????????????????0010111 : begin //auipc
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= imm3112;
			alu_data1_o <= PC_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b?????????????????000?????1100011 : begin //beq
			J_en_o <= 1'b1;
			J_data_o <= reg_data_i;
			J_data1_o <= reg1_data_i;
			J_addr_o <= PC_i;
			J_addrp_o <= imm121;
			J_how_o <= 3'h0;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????001?????1100011 : begin //bne
			J_en_o <= 1'b1;
			J_data_o <= reg_data_i;
			J_data1_o <= reg1_data_i;
			J_addr_o <= PC_i;
			J_addrp_o <= imm121;
			J_how_o <= 3'h1;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????100?????1100011 : begin //blt
			J_en_o <= 1'b1;
			J_data_o <= reg_data_i;
			J_data1_o <= reg1_data_i;
			J_addr_o <= PC_i;
			J_addrp_o <= imm121;
			J_how_o <= 3'h2;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????101?????1100011 : begin //bge
			J_en_o <= 1'b1;
			J_data_o <= reg_data_i;
			J_data1_o <= reg1_data_i;
			J_addr_o <= PC_i;
			J_addrp_o <= imm121;
			J_how_o <= 3'h3;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????110?????1100011 : begin //bltu
			J_en_o <= 1'b1;
			J_data_o <= reg_data_i;
			J_data1_o <= reg1_data_i;
			J_addr_o <= PC_i;
			J_addrp_o <= imm121;
			J_how_o <= 3'h4;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????111?????1100011 : begin //bgeu
			J_en_o <= 1'b1;
			J_data_o <= reg_data_i;
			J_data1_o <= reg1_data_i;
			J_addr_o <= PC_i;
			J_addrp_o <= imm121;
			J_how_o <= 3'h5;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????????????1101111 : begin //jal
			J_en_o <= 1'b1;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= PC_i;
			J_addrp_o <= imm201;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= PC_i;
			alu_data1_o <= 32'h4;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????000?????1100111 : begin //jalr
			J_en_o <= 1'b1;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= reg_data_i;
			J_addrp_o <= imm110i;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= PC_i;
			alu_data1_o <= 32'h4;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????000?????0000011 : begin //lb
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h10;
			c_int_o <= 1'b0;
		end

		32'b?????????????????001?????0000011 : begin //lh
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h20;
			c_int_o <= 1'b0;
		end

		32'b?????????????????010?????0000011 : begin //lw
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h30;
			c_int_o <= 1'b0;
		end

		32'b?????????????????100?????0000011 : begin //lbu
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h40;
			c_int_o <= 1'b0;
		end

		32'b?????????????????101?????0000011 : begin //lhu
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h50;
			c_int_o <= 1'b0;
		end

		32'b?????????????????000?????0100011 : begin //sb
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110s;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= reg1_data_i;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b1;
			alu_how_o <= 8'h60;
			c_int_o <= 1'b0;
		end

		32'b?????????????????001?????0100011 : begin //sh
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110s;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= reg1_data_i;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b1;
			alu_how_o <= 8'h70;
			c_int_o <= 1'b0;
		end

		32'b?????????????????010?????0100011 : begin //sw
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= imm110s;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= reg1_data_i;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b1;
			alu_how_o <= 8'h80;
			c_int_o <= 1'b0;
		end

		32'b0000????????00000000000000001111 : begin //fence
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b00000000000000000001000000001111 : begin //fence.i
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b0000000000000000000000001110011 : begin //ecall
			J_en_o <= 1'b1;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= csr_mtvec_i;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= csr_mstatus_i;
			alu_data1_o <= PC_i+32'h4;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'h00000800;
			alu_mtval_o <= mem_data_i;
			alu_where_o <= 2'h3;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b00000000000000000000000001110011 : begin //ebreak
			J_en_o <= 1'b1;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= csr_mtvec_i;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= csr_mstatus_i;
			alu_data1_o <= PC_i+32'h4;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'h00000008;
			alu_mtval_o <= mem_data_i;
			alu_where_o <= 2'h3;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		32'b?????????????????001?????1110011 : begin //csrrw
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= csr_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= csr;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'h2;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b?????????????????010?????1110011 : begin //csrrs
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= csr_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= csr;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'h2;
			alu_how_o <= 8'h3;
			c_int_o <= 1'b0;
		end

		32'b?????????????????011?????1110011 : begin //csrrc
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= reg_data_i;
			alu_data1_o <= csr_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= csr;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'h2;
			alu_how_o <= 8'h2;
			c_int_o <= 1'b0;
		end

		32'b?????????????????101?????1110011 : begin //csrrwi
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= zimm;
			alu_data1_o <= csr_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= csr;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'h2;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b?????????????????110?????1110011 : begin //csrrsi
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= zimm;
			alu_data1_o <= csr_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= csr;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'h2;
			alu_how_o <= 8'h3;
			c_int_o <= 1'b0;
		end

		32'b?????????????????111?????1110011 : begin //csrrci
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= zimm;
			alu_data1_o <= csr_data_i;
			alu_reg_addr_o <= rd;
			alu_csr_addr_o <= csr;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'h2;
			alu_how_o <= 8'h2;
			c_int_o <= 1'b0;
		end

		32'b00010000010100000000000001110011 : begin //wfi
			J_en_o <= 1'b0;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= 32'b0;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b0;
		end

		32'b00110000001000000000000001110011 : begin //mret
			J_en_o <= 1'b1;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= csr_mepc_i;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b0;
			alu_data_o <= 32'b0;
			alu_data1_o <= 32'b0;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'b0;
			alu_mtval_o <= 32'b0;
			alu_where_o <= 2'b0;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

		default : begin //default
			J_en_o <= 1'b1;
			J_data_o <= 32'b0;
			J_data1_o <= 32'b0;
			J_addr_o <= csr_mtvec_i;
			J_addrp_o <= 32'b0;
			J_how_o <= 3'b0;
			alu_en_o <= 1'b1;
			alu_data_o <= csr_mstatus_i;
			alu_data1_o <= PC_i;
			alu_reg_addr_o <= 5'b0;
			alu_csr_addr_o <= 12'b0;
			alu_mcause_o <= 32'h02;
			alu_mtval_o <= mem_data_i;
			alu_where_o <= 2'h3;
			alu_how_o <= 8'h0;
			c_int_o <= 1'b1;
		end

	endcase


	end
	end else begin
		J_en_o <= 1'b0;
		J_data_o <= 32'b0;
		J_data1_o <= 32'b0;
		J_addr_o <= 32'b0;
		J_addrp_o <= 32'b0;
		J_how_o <= 3'b0;
		alu_en_o <= 1'b0;
		alu_data_o <= 32'b0;
		alu_data1_o <= 32'b0;
		alu_reg_addr_o <= 5'b0;
		alu_csr_addr_o <= 12'b0;
		alu_mcause_o <= 32'b0;
		alu_mtval_o <= 32'b0;
		alu_where_o <= 2'b0;
		alu_how_o <= 8'h0;
		c_int_o <= 1'b0;
	end
end

endmodule
